
import copy, types

                 
class PytmlError(Exception):
    def __init__(self, *args, **kwds):
        Exception.__init__(self, *args, **kwds)

    
class AbstractTag(object):
    def __init__(self, inTagType):   
        self.__tagType = inTagType
        
        self.__parentTag = None
        self.__childrenTags = [] 
    
    def __repr__(self):
        return '(%s, %s)' %(self.__tagType, object.__repr__(self))
    
    def __len__(self):
        return len(self.__childrenTags)
            
    def _getChildrenTagsByReference(self):
        return self.__childrenTags
    
    def getParentTag(self):
        return self.__parentTag
    
    def hasParentTag(self):
        if self.__parentTag:
            return True
        else:
            return False
            
    def removeParentTag(self):
        if self.__parentTag:
            parentChildren = self.__parentTag._getChildrenTagsByReference()
            parentChildren.remove(self)
            self.__parentTag = None
        
    def setParentTag(self, inParentTag, inChildPosition=-1):
        if isinstance(inParentTag, AbstractTag):
            self.removeParentTag()
            self.__parentTag = inParentTag
            parentChildren = self.__parentTag._getChildrenTagsByReference()
            if inChildPosition<0: 
                inChildPosition = len(parentChildren)-(1+inChildPosition)
            parentChildren.insert(inChildPosition, self)
               
        else:
            raise PytmlError, 'Impossible to set parent. '+`inParentTag`+' is not an instance of class Tag'
     
    def addTag(self, *args, **kwds):
        ''' this should always reimplemented in any subclass '''
        raise PytmlError, 'addTag method not implemented for class %s' %repr(self) 

    
    def getChildrenTags(self):
        return copy.copy(self.__childrenTags)
    
    def getChildrenTagsByType(self, inType):
        returnChildren = []
        for child in self.__childrenTags:
            if child.getType() == inType:
                returnChildren.append(child)
        return returnChildren
    
    def getChildrenTagsByAttribute(self, inAttr, inAttrValue):
        returnChildren = []
        for child in self.__childrenTags:
            attributes = child.getAttributes()
            if inAttr in attributes.keys():
                if attributes[inAttr] == inAttrValue:
                    returnChildren.append(child)
        return returnChildren
    
    def removeAllChildren(self):
        self.__childrenTags = []
        
    def getType(self):
        return self.__tagType
    
    def toString(self, *args, **kwds):
        ''' this should always reimplemented in any subclass '''
        raise PytmlError, 'toString method not implemented for class %s' %repr(self) 
    
    
    